﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Reflection;
using System.ComponentModel;
using System.Configuration;

namespace ARR.UI.Models
{
    public static class ModelFactory
    {
        public static bool UseMocks 
        {
            get
            {
                return Convert.ToBoolean(ConfigurationManager.AppSettings["UseMockModels"]);
            }
        }

        public static T GetInstance<T>(params object[] args) where T: IModelBase
        {
            Type interfaceType = typeof(T);

            var results = from type in Assembly.GetExecutingAssembly().GetTypes()
                          where interfaceType.IsAssignableFrom(type)
                          select type;
            
            Type attributeType = UseMocks ? typeof(MockModelAttribute) : typeof(RealModelAttribute);

            T model = default(T);

            foreach (Type type in results)
            {
                if (HasAttribute(type, attributeType))
                {
                    model = (T)Activator.CreateInstance(type, args);
                }
            }

            if (model == null)
                throw new Exception("No se pudo crear el modelo requerido, verificar que las clases esten decoradas con los Atributos 'MockModel' y 'RealModel'");

            return model;
        }

        private static bool HasAttribute(Type type, Type attribute)
        {
            if (!typeof(Attribute).IsAssignableFrom(attribute))
                throw new ArgumentException("attribute does not extend System.Attribute.");
            
            return type.GetCustomAttributes(attribute, true).Length > 0;
        }
    }
}
